package com.dzb.langchain4j.common.config;

import com.dzb.langchain4j.common.tools.NyistAiTools;
import com.dzb.langchain4j.store.MongoChatMemoryStore;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;

/**
 * 1.
 *
 * @ClassName AiConfig
 * @Description
 * @Author 418167
 * @Date 2025/07/23/10:13
 */
@Configuration
public class AiConfig {

    public interface AssistantAi {
        String chat(String userMessage);

        // 流式响应
        TokenStream chatStream(String userMessage);
    }

    @Bean
    public AssistantAi assistant(ChatLanguageModel qwenChatModel
            , StreamingChatLanguageModel qwenStreamingChatModel) {

        ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);

        AssistantAi assistant = AiServices.builder(AssistantAi.class)
                .chatLanguageModel(qwenChatModel)
                .streamingChatLanguageModel(qwenStreamingChatModel)
                .chatMemory(chatMemory)
                .build();

        return assistant;
    }


    public interface AssistantAiUnique {
        String chat(@MemoryId int memoryId, @UserMessage String userMessage);

        // 流式响应
        TokenStream chatStream(@MemoryId int memoryId, @UserMessage String userMessage);
    }

    @Bean
    public AssistantAiUnique assistantUnique(ChatLanguageModel qwenChatModel
            , StreamingChatLanguageModel qwenStreamingChatModel) {

        // 放在内存中的隔离式对话
        AssistantAiUnique assistant = AiServices.builder(AssistantAiUnique.class)
                .chatLanguageModel(qwenChatModel)
                .streamingChatLanguageModel(qwenStreamingChatModel)
                // 隔离式存储对话信息
                .chatMemoryProvider(memoryId -> MessageWindowChatMemory
                        .builder()
                        .maxMessages(10)
                        .id(memoryId)
                        .build()
                )
                .build();

        return assistant;
    }


    public interface AssistantAiUniqueSql {
        String chat(@MemoryId int memoryId, @UserMessage String userMessage);

        // 流式响应
        TokenStream chatStream(@MemoryId int memoryId, @UserMessage String userMessage);
    }

    @Autowired
    private MongoChatMemoryStore mongoChatMemoryStore;

    @Bean
    public AssistantAiUniqueSql assistantUniqueSql(ChatLanguageModel qwenChatModel
            , StreamingChatLanguageModel qwenStreamingChatModel
            , MongoTemplate mongoTemplate
    ) {
        // 放在 mongodb 的隔离式对话
        // 使用new 的方式在bean创建的时候会绕过spring的依赖注入机制， spring无法自动注入mongoTemplate
        // 所以导致了mongoTemplate为null
        // MongoChatMemoryStore mongoChatMemoryStore = new MongoChatMemoryStore(mongoTemplate);
        // 需要改为 Autowired注入的形式/或者在 new的时候将MongoTemplate传入进来
        // 将 memoryId 和对话内容记忆在 mongodb中
        ChatMemoryProvider chatMemoryProvider = memoryId -> MessageWindowChatMemory
                .builder()
                .id(memoryId)
                .maxMessages(10)
                .chatMemoryStore(mongoChatMemoryStore)
                .build();
        AssistantAiUniqueSql assistantAiUniqueSql = AiServices.builder(AssistantAiUniqueSql.class)
                .chatLanguageModel(qwenChatModel)
                .streamingChatLanguageModel(qwenStreamingChatModel)
                // 隔离式存储对话信息
                .chatMemoryProvider(chatMemoryProvider)
                .build();

        return assistantAiUniqueSql;
    }


    public interface AssistantAiUniqueSqlSysMgs {
        @SystemMessage("你是nyist学校的招生助手")
        String chat(@MemoryId int memoryId, @UserMessage String userMessage);

        // 流式响应
        @SystemMessage("# 你是nyist学校的招生智能聊天助手." +
                "## 要求如下:" +
                "0. 你正在通过在线聊天系统和学生以及学生家长/老师等互动" +
                "1. 请以友好,乐于助人且愉快的方式来回复" +
                "2. 提供服务的时候始终需要从用户获取以下信息: 高考成绩,学生姓名,所在地区" +
                "3. 请讲中文, 在不知道如何回答时请回复'建议联系学校官方电话:0571-8686886'" +
                "# 始终在结尾处换行输出: 今天的日期: {{current_date}}, 作者: gscsd17")
        TokenStream chatStream(@MemoryId int memoryId
                , @UserMessage String userMessage
                , @V("current_date") String currentDate
        );
    }


    @Bean
    public AssistantAiUniqueSqlSysMgs assistantAiUniqueSqlSysMgs(
            ChatLanguageModel qwenChatModel
            , StreamingChatLanguageModel qwenStreamingChatModel
    ) {
        // 放在 mongodb 的隔离式对话
        // 使用new 的方式在bean创建的时候会绕过spring的依赖注入机制， spring无法自动注入mongoTemplate
        // 所以导致了mongoTemplate为null
        // MongoChatMemoryStore mongoChatMemoryStore = new MongoChatMemoryStore(mongoTemplate);
        // 需要改为 Autowired注入的形式/或者在 new的时候将MongoTemplate传入进来
        // 将 memoryId 和对话内容记忆在 mongodb中
        ChatMemoryProvider chatMemoryProvider = memoryId -> MessageWindowChatMemory
                .builder()
                .id(memoryId)
                .maxMessages(10)
                .chatMemoryStore(mongoChatMemoryStore)
                .build();
        AssistantAiUniqueSqlSysMgs assistantAiUniqueSql = AiServices.builder(AssistantAiUniqueSqlSysMgs.class)
                .chatLanguageModel(qwenChatModel)
                .streamingChatLanguageModel(qwenStreamingChatModel)
                // 隔离式存储对话信息
                .chatMemoryProvider(chatMemoryProvider)
                .build();

        return assistantAiUniqueSql;
    }


    public interface AssistantAiUniqueSqlTools {
        @SystemMessage("你是nyist学校的招生助手")
        String chat(@MemoryId int memoryId, @UserMessage String userMessage);

        // 流式响应
        @SystemMessage("# 你是nyist学校的招生智能聊天助手." +
                "## 要求如下:" +
                "0. 你正在通过在线聊天系统和学生以及学生家长/老师等互动" +
                "1. 请以友好,乐于助人且愉快的方式来回复" +
                "2. 提供服务的时候始终需要从用户获取以下信息: 高考成绩,学生姓名,所在地区" +
                "3. 请讲中文, 在不知道如何回答时请回复'建议联系学校官方电话:0571-8686886'" +
                "# 始终在结尾处换行输出: 今天的日期: {{current_date}}, 作者: gscsd17")
        TokenStream chatStream(@MemoryId int memoryId
                , @UserMessage String userMessage
                , @V("current_date") String currentDate
        );
    }


    @Bean
    public AssistantAiUniqueSqlTools assistantAiUniqueSqlTools(
            ChatLanguageModel qwenChatModel
            , StreamingChatLanguageModel qwenStreamingChatModel
            , NyistAiTools tools
    ) {
        // 放在 mongodb 的隔离式对话
        // 使用new 的方式在bean创建的时候会绕过spring的依赖注入机制， spring无法自动注入mongoTemplate
        // 所以导致了mongoTemplate为null
        // MongoChatMemoryStore mongoChatMemoryStore = new MongoChatMemoryStore(mongoTemplate);
        // 需要改为 Autowired注入的形式/或者在 new的时候将MongoTemplate传入进来
        // 将 memoryId 和对话内容记忆在 mongodb中
        ChatMemoryProvider chatMemoryProvider = memoryId -> MessageWindowChatMemory
                .builder()
                .id(memoryId)
                .maxMessages(10)
                .chatMemoryStore(mongoChatMemoryStore)
                .build();
        AssistantAiUniqueSqlTools assistantAiUniqueSql = AiServices.builder(AssistantAiUniqueSqlTools.class)
                .chatLanguageModel(qwenChatModel)
                .streamingChatLanguageModel(qwenStreamingChatModel)
                // 隔离式存储对话信息
                .chatMemoryProvider(chatMemoryProvider)
                .tools(tools)
                .build();

        return assistantAiUniqueSql;
    }


}
